
package com.gitee.jmash.storage.service;

import java.util.List;
import java.util.Set;
import java.util.UUID;
import com.gitee.jmash.common.grpc.GrpcContext;
import com.gitee.jmash.common.lock.DistributedLock;
import com.gitee.jmash.common.security.JmashPrincipal;
import com.gitee.jmash.common.utils.UUIDUtil;
import com.gitee.jmash.core.jaxrs.ParamsValidationException;
import com.gitee.jmash.core.orm.cdi.JpaTenantService;
import com.gitee.jmash.core.transaction.JakartaTransaction;
import com.gitee.jmash.storage.entity.StorageOrganUserEntity;
import com.gitee.jmash.storage.entity.StorageOrganUserEntity.StorageOrganUserPk;
import com.gitee.jmash.storage.mapper.StorageOrganUserMapper;
import jakarta.enterprise.inject.Typed;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import jakarta.transaction.Transactional.TxType;
import jakarta.validation.ValidationException;
import jakarta.validation.executable.ValidateOnExecution;
import jmash.storage.protobuf.StorageOrganUserCreateReq;

/**
 * storage_organ_user写服务.
 *
 * @author <a href="mailto:service@crenjoy.com">crenjoy</a>
 */
@Typed(StorageOrganUserWrite.class)
@Transactional(TxType.REQUIRED)
@JpaTenantService
@ValidateOnExecution
public class StorageOrganUserWriteBean extends StorageOrganUserReadBean
    implements StorageOrganUserWrite, JakartaTransaction {

  @Inject
  DistributedLock lock;

  @Override
  @PersistenceContext(unitName = "WriteStorage")
  public void setEntityManager(EntityManager entityManager) {
    this.tem.setEntityManager(entityManager, true);
  }

  @Override
  public StorageOrganUserEntity insert(StorageOrganUserCreateReq req) {
    StorageOrganUserEntity entity = storageOrganUserDao
        .find(new StorageOrganUserPk(req.getUnifiedId(), UUIDUtil.fromString(req.getOrganId())));
    // 1.业务校验.
    // 2.仅校验,不执行.
    if (req.getValidateOnly()) {
      return entity;
    }
    // 3.检查是否重复请求.
    if (!lock.lock(req.getRequestId(), 60)) {
      throw new ParamsValidationException("requestId", "客户端发起重复请求");
    }
    entity = addOrganUser(req);
    return entity;
  }

  @Override
  public StorageOrganUserEntity addOrganUser(StorageOrganUserCreateReq req) {
    StorageOrganUserEntity user = storageOrganUserDao
        .find(new StorageOrganUserPk(req.getUnifiedId(), UUIDUtil.fromString(req.getOrganId())));
    if (user != null && req.getIsDefault()) {
      user.setOrderBy(1);
      storageOrganUserDao.insOrderBy(req.getUnifiedId());
      storageOrganUserDao.merge(user);
      return user;
    } else if (user != null) {
      return user;
    }

    user = new StorageOrganUserEntity();
    user.setOrganId(UUIDUtil.fromString(req.getOrganId()));
    user.setUnifiedId(req.getUnifiedId());
    if (req.getIsDefault()) {
      user.setOrderBy(1);
      storageOrganUserDao.insOrderBy(req.getUnifiedId());
    } else {
      Integer orderBy = storageOrganUserDao.getMaxOrderBy(req.getUnifiedId());
      user.setOrderBy(orderBy);
    }
    // 4.执行业务(创建人及时间内部处理.)
    storageOrganUserDao.persist(user);
    return user;
  }

  @Override
  public StorageOrganUserEntity delete(StorageOrganUserPk entityId) {
    StorageOrganUserEntity entity = storageOrganUserDao.removeById(entityId);
    return entity;
  }

  @Override
  public Integer batchDelete(Set<StorageOrganUserPk> entityIds) {
    int i = 0;
    for (StorageOrganUserPk entityId : entityIds) {
      storageOrganUserDao.removeById(entityId);
      i++;
    }
    return i;
  }

  @Override
  public StorageOrganUserEntity setMyDefaultOrgan(UUID organId) {
    JmashPrincipal principal = GrpcContext.getPrincipal();
    StorageOrganUserEntity entity =
        storageOrganUserDao.findMyByOrganId(principal.getUnifiedId(), organId);
    if (null == entity) {
      throw new ValidationException("找不到实体:" + organId);
    }
    List<StorageOrganUserEntity> organList =
        storageOrganUserDao.findMyList(principal.getUnifiedId());
    organList.remove(entity);
    organList.add(0, entity);
    int i = 1;
    for (StorageOrganUserEntity organEntity : organList) {
      organEntity.setOrderBy(i++);
    }
    storageOrganUserDao.save(organList);
    return entity;
  }

}
